/* 
 *  Syntelos XB
 *  Copyright (C) 2006 John Pritchard.
 *
 *  This program is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU General Public License as
 *  published by the Free Software Foundation; either version 2 of
 *  the License, or (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *  General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
 *  02111-1307 USA
 */

package syntelos.xb;

/** 
 * <p> Child of {@link Class}, {@link Field}, {@link Method} or {@link
 * syntelos.xb.at.Code}. </p>
 * 
 * @author jdp
 */
public class Attributes 
    extends Base
{
    public final static syntelos.iou.dom.Name NAME = new syntelos.iou.dom.impl.Name(ELEMENT_NODE,"http://www.syntelos.org/xb","xb:attributes");


    public Attributes(org.w3c.dom.Document doc, syntelos.iou.dom.Name name){
        super(doc,name);
    }
    public Attributes(org.w3c.dom.Document doc){
        this(doc,NAME);
    }
    public Attributes(){
        this(DOC_NIL);
    }

    public syntelos.xb.at.Code getCode(){
        syntelos.xb.at.Code elattr = (syntelos.xb.at.Code)this.getChildByName("code");
        if (null == elattr){
            elattr = new syntelos.xb.at.Code();
            this.appendChild(elattr);
        }
        return elattr;
    }
    public syntelos.xb.at.Exceptions getExceptions(){
        syntelos.xb.at.Exceptions elattr = (syntelos.xb.at.Exceptions)this.getChildByName("exceptions");
        if (null == elattr){
            elattr = new syntelos.xb.at.Exceptions();
            this.appendChild(elattr);
        }
        return elattr;
    }
    public syntelos.xb.at.Synthetic getSynthetic(){
        syntelos.xb.at.Synthetic elattr = (syntelos.xb.at.Synthetic)this.getChildByName("synthetic");
        if (null == elattr){
            elattr = new syntelos.xb.at.Synthetic();
            this.appendChild(elattr);
        }
        return elattr;
    }
    public syntelos.xb.at.Deprecated getDeprecated(){
        syntelos.xb.at.Deprecated elattr = (syntelos.xb.at.Deprecated)this.getChildByName("deprecated");
        if (null == elattr){
            elattr = new syntelos.xb.at.Deprecated();
            this.appendChild(elattr);
        }
        return elattr;
    }
    public syntelos.xb.at.SourceFile getSourceFile(){
        syntelos.xb.at.SourceFile elattr = (syntelos.xb.at.SourceFile)this.getChildByName("source-file");
        if (null == elattr){
            elattr = new syntelos.xb.at.SourceFile();
            this.appendChild(elattr);
        }
        return elattr;
    }
    public syntelos.xb.at.ConstantValue getConstantValue(){
        syntelos.xb.at.ConstantValue elattr = (syntelos.xb.at.ConstantValue)this.getChildByName("constant-value");
        if (null == elattr){
            elattr = new syntelos.xb.at.ConstantValue();
            this.appendChild(elattr);
        }
        return elattr;
    }
    public syntelos.xb.at.InnerClasses getInnerClasses(){
        syntelos.xb.at.InnerClasses elattr = (syntelos.xb.at.InnerClasses)this.getChildByName("inner-classes");
        if (null == elattr){
            elattr = new syntelos.xb.at.InnerClasses();
            this.appendChild(elattr);
        }
        return elattr;
    }
    public syntelos.xb.at.LineNumberTable getLineNumberTable(){
        syntelos.xb.at.LineNumberTable elattr = (syntelos.xb.at.LineNumberTable)this.getChildByName("line-number-table");
        if (null == elattr){
            elattr = new syntelos.xb.at.LineNumberTable();
            this.appendChild(elattr);
        }
        return elattr;
    }
    public syntelos.xb.at.LocalVariableTable getLocalVariableTable(){
        syntelos.xb.at.LocalVariableTable elattr = (syntelos.xb.at.LocalVariableTable)this.getChildByName("local-variable-table");
        if (null == elattr){
            elattr = new syntelos.xb.at.LocalVariableTable();
            this.appendChild(elattr);
        }
        return elattr;
    }
    public syntelos.xb.at.SourceDebugExtension getSourceDebugExtension(){
        syntelos.xb.at.SourceDebugExtension elattr = (syntelos.xb.at.SourceDebugExtension)this.getChildByName("source-debug-extension");
        if (null == elattr){
            elattr = new syntelos.xb.at.SourceDebugExtension();
            this.appendChild(elattr);
        }
        return elattr;
    }
    public int atlen(){
        int acc = 2;
        int count = this.countChildNodes();
        if (0 < count){
            org.w3c.dom.NodeList children = this.getChildNodes();
            syntelos.xb.Attribute attr;
            for (int cc = 0; cc < count; cc++){
                attr = (syntelos.xb.Attribute)children.item(cc);
                acc += (6 + attr.atlen());
            }
        }
        return acc;
    }
    public void readCF(IO.Uri src, CF.Reader reader)
        throws java.io.IOException
    {
        CF.Constants constants = this.getConstants();
        org.w3c.dom.Document doc = this.getOwnerDocument();
        int count = reader.readUnsignedShort();
        syntelos.xb.Attribute attr;
        int atname_index;
        java.lang.String atname;
        CF.Constants.Utf8 atname_const;
        java.lang.String classname;
        java.lang.Class jclass;
        for (int cc = 0; cc < count; cc++){
            atname_index = reader.readUnsignedShort();
            atname_const = constants.getConstUtf8(atname_index);
            if (null != atname_const){
                atname = atname_const.getString();
                if (null != atname){
                    try {
                        classname = syntelos.iou.chbuf.cat("syntelos.xb.at.",
                                                               atname);
                        jclass = java.lang.Class.forName(classname);

                        attr = (syntelos.xb.Attribute)NewInstance(jclass,doc);
                    }
                    catch (java.lang.IllegalStateException ils){

                        attr = new syntelos.xb.Attribute.Any(doc);
                    }
                    catch (java.lang.ClassNotFoundException cnf){

                        attr = new syntelos.xb.Attribute.Any(doc);
                    }
                    this.appendChild(attr);
                    attr.setAttributeName(atname_const);
                    attr.readCF(src,reader);
                }
                else
                    throw new Error.State("Missing string value for UTF8 constant at CP Index ("+atname_const.toString()+").");
            }
            else
                throw new Error.State("Missing UTF8 constant at CP Index ("+atname_const.toString()+").");
        }
    }
    public void writeCF(IO.Uri dst, CF.Writer writer)
        throws java.io.IOException
    {
        int count = this.countChildNodes();
        writer.writeShort(count);
        if (0 < count){
            org.w3c.dom.NodeList children = this.getChildNodes();
            syntelos.xb.Attribute attr;
            for (int cc = 0; cc < count; cc++){
                attr = (syntelos.xb.Attribute)children.item(cc);
                attr.writeCF(dst,writer);
            }
        }
    }
}
